// 树形结构数据工具函数
/**
 * @function treeToList
 * @description 树形转数组
 * @param {*} tree 数组对象
 * @returns {Array}
 */
export function treeToList(tree) {
  let queen = [];
  const out = [];
  queen = queen.concat(tree);
  while (queen.length) {
    const first = queen.shift();
    const { children, ...item } = first;
    if (children) {
      queen = queen.concat(children);
    }
    out.push(item);
  }
  return out;
}

export function arrayToTree(arr) {
  if (!Array.isArray(arr) || arr.length < 1) return null;
  const list = arr.filter((item) => item.parentId === "0");
  const addChildren = (node, dataList) => {
    const children = dataList
      .filter((item) => item.parentId === node.id)
      .map((item) => addChildren(item, dataList));
    return { ...node, children };
  };
  return list.map((root) => addChildren(root, arr));
}

/**
 * @description 重设树形数据属性
 * @param {Array} treeNode 树形数据
 * @param {Object} replaceFields 非必传,示例:{ children: 'children', key: 'id', title: 'title } 替换 treeNode 中key,children
 * @param {Function} callback 函数接收树节点与父级节点作为参数,返回新的节点对象
 * @returns {Array}
 */
export function resetTree(treeNode, replaceFields, callback) {
  if (!treeNode || !treeNode.length) return;
  function fn(treeNode, parentNode, level) {
    for (let i = 0; i < treeNode.length; i += 1) {
      let item = treeNode[i];
      if (replaceFields) {
        item.id = item[replaceFields.key];
        item.key = item[replaceFields.key];
        item.title = item[replaceFields.title];
        if (item[replaceFields.children]) {
          item.children = item[replaceFields.children];
        }
      }
      // 节点父级id
      if (parentNode) {
        item.parentId = parentNode.id;
        // parentIds:节点所有父级id集合
        item.parentIds = [...parentNode.parentIds, item.parentId];
      } else {
        item.parentId = item.parentId || 0;
        item.parentIds = [item.parentId];
      }
      // 节点所在层级
      item.level = level || 1;
      if (typeof callback === "function") {
        item = callback(item, parentNode);
      }
      const children = item.children;
      if (children && children.length > 0) {
        fn(children, item, item.level + 1);
      }
    }
  }
  fn(treeNode);
  return treeNode;
}

/**
 * @function getNodeById
 * @description 根据id获取节点
 * @param	{Array} treeNode  树形数据
 * @param {Number|String} id  树形数据节点id
 * @param {String} key  查询主键,默认id
 * @return	{Object}
 */
export function getNodeById(treeNode, id, key = "id") {
  if (!treeNode || !treeNode.length) return;
  let node;
  function fn(treeNode, id, key) {
    for (let i = 0; i < treeNode.length; i += 1) {
      const item = treeNode[i];
      if (item[key] === id) {
        node = item;
        break;
      } else {
        const children = item.children;
        if (children && children.length > 0) {
          fn(children, id, key);
        }
      }
    }
  }
  fn(treeNode, id, key);
  return node;
}
/**
 * @function getParentNodeById
 * @description 根据id获取父级树节点
 * @param	{Array} treeNode  树形数据
 * @param {Number|String} id  树形数据节点id
 * @param {String} key  查询主键,默认id
 * @return	{Object}
 */
export function getParentNodeById(treeNode, id, key = "id") {
  if (!treeNode || !treeNode.length) return;
  let parentNode;
  for (let i = 0; i < treeNode.length; i++) {
    const node = treeNode[i];
    if (node.children) {
      if (node.children.some((item) => item[key] === id)) {
        parentNode = node;
      } else if (getParentNodeById(node.children, id, key)) {
        parentNode = getParentNodeById(node.children, id, key);
      }
    }
  }
  return parentNode;
}
/**
 * @function getAllParentNodeById
 * @description 根据id获取父级树节点
 * @param	{Array} treeNode  树形数据
 * @param {Number|String} id  树形数据节点id
 * @param {Object} replaceFields 查询主键,
 * @return	{Object}
 */
export function getAllParentNodeById(
  treeNode,
  id,
  replaceFields = { key: "id", parentKey: "parentId" }
) {
  let parentArr = [];
  if (treeNode.length == 0) {
    if (id) {
      parentArr.unshift(treeNode);
    }
    return parentArr;
  }
  const findParent = (data, nodeId) => {
    for (var i = 0; i < data.length; i++) {
      let node = data[i];
      if (node[replaceFields.key] == nodeId) {
        parentArr.unshift(node);
        // 注意这里是传入的tree，不要写成data了，不然遍历的时候一直都是node.children,不是从最顶层开始遍历的
        findParent(treeNode, node[replaceFields.parentKey]);
        break;
      } else {
        if (node.children) {
          findParent(node.children, nodeId);
        }
      }
    }
    return parentArr;
  };
  parentArr = findParent(treeNode, id);
  return parentArr;
}
/**
 * @function	filterNodes
 * @description	根据节点属性值过滤节点，返回新的树
 * @param {Array} treeNode
 * @param {Function} callback 函数接收树节点作为参数,
 * 返回true将过滤该节点
 * @return	{Array}
 */
export function filterNodes(treeNode, callback) {
  if (!treeNode || !treeNode.length) return;
  function fn(treeNode, parentNode) {
    for (let i = 0; i < treeNode.length; i++) {
      const item = treeNode[i];
      if (typeof callback === "function" && callback(item)) {
        item.level === 1
          ? treeNode.splice(i, 1)
          : parentNode.children.splice(i, 1);
      }
      const children = item.children;
      if (children && children.length > 0) {
        fn(children, item);
      }
    }
  }
  fn(treeNode);
  return treeNode;
}
